package com.rybbaby.tss.platform.initializer;

import com.rybbaby.tss.core.initializer.AbstractAutomaticInit;
import com.rybbaby.tss.core.utils.SpringApplicationContextUtil;
import com.rybbaby.tss.core.utils.StringUtils;
import com.rybbaby.tss.platform.sysCitys.entity.SysCitys;
import com.rybbaby.tss.platform.sysCitys.service.ISysCitysService;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @description 系统城市初始化器
 * 
 * @author 谢进伟
 * 
 * @createDate 2016年12月12日 上午9:55:23
 */
public class SysCityInitializer extends AbstractAutomaticInit {
	
	/** ehcache缓存管理 **/
	private static CacheManager ehcacheManager;
	/** 操作权限缓存容器 **/
	private static Cache citysEhcache;
	/** 缓存前缀 **/
	private static final String CACHEPREFIX = "city_";
	
	static {
		ehcacheManager = SpringApplicationContextUtil.getContext().getBean(CacheManager.class);
		citysEhcache = ehcacheManager.getCache("citysEhcache");
	}
	
	@Override
	public void autoInit() {
		loadAll();
	}
	
	/**
	 * 加载并缓存所有城市
	 */
	@SuppressWarnings("unchecked")
	public static void loadAll() {
		ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
		cachedThreadPool.execute(new Runnable() {
			
			@Override
			public void run() {
				ISysCitysService sysCitysService = SpringApplicationContextUtil.getContext().getBean(ISysCitysService.class);
				// 所有类型
				List<SysCitys> sysCityList = sysCitysService.loadAll();
				// 所有类型缓存
				String sql = "SELECT levelType FROM sys_citys GROUP BY levelType";
				List<Map<String , Object>> levelTypes = sysCitysService.findForJdbc(sql , new Object []{ });
				if(levelTypes != null && !levelTypes.isEmpty()) {
					Object levelTypeArr [] = new Object [levelTypes.size()];
					int index = 0;
					for(Map<String , Object> typeMap : levelTypes) {
						if(typeMap != null && !typeMap.isEmpty()) {
							levelTypeArr[index++] = typeMap.get("levelType");
						}
					}
					for(SysCitys city : sysCityList) {
						// 按Id缓存
						String key_city_id = CACHEPREFIX + city.getId();
						Element element_key_id = new Element(key_city_id , city);
						citysEhcache.put(element_key_id);
						// 按levelType缓存
						String key_city_type = CACHEPREFIX + city.getLevelType();
						Element element = citysEhcache.get(key_city_type);
						if(element != null) {
							Object objectValue = element.getObjectValue();
							if(objectValue != null && objectValue instanceof List) {
								((List<SysCitys>)objectValue).add(city);
							}
						} else {
							List<SysCitys> citys = new ArrayList<SysCitys>();
							citys.add(city);
							Element element_key_levelType = new Element(key_city_type , citys);
							citysEhcache.put(element_key_levelType);
						}
					}
					// 缓存所有城市
					Element element = new Element(CACHEPREFIX + "allCitys" , sysCityList);
					citysEhcache.put(element);
				}
			}
			
		});
		cachedThreadPool.shutdown();
	}
	
	/**
	 * 根据城市Id获取城市对象
	 * 
	 * @param cityId
	 *            城市Id
	 * @return
	 */
	public static SysCitys getCityById(String cityId) {
		Element element = citysEhcache.get(CACHEPREFIX + cityId);
		if(element != null) {
			return (SysCitys)element.getObjectValue();
		} else {
			return null;
		}
	}
	
	/**
	 * 根据类型获取城市/省份
	 * 
	 * @param levelType
	 *            类型值
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static List<SysCitys> getCitysByLevelType(Object levelType) {
		Element element = citysEhcache.get(CACHEPREFIX + levelType);
		if(element != null) {
			return (List<SysCitys>)element.getObjectValue();
		} else {
			return null;
		}
	}
	
	/**
	 * 根据父id获取下级城市/省份列表
	 * 
	 * @param parentId
	 *            父id
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static List<SysCitys> getChildrenCity(String parentId) {
		List<SysCitys> result = new ArrayList<SysCitys>();
		if(StringUtils.isBlank(parentId)) {
			return result;
		}
		if(citysEhcache != null) {
			Element element = citysEhcache.get(CACHEPREFIX + "allCitys");
			if(element != null) {
				Object objectValue = element.getObjectValue();
				if(objectValue != null && objectValue instanceof List) {
					((List<SysCitys>)objectValue).parallelStream().filter((t) -> {
						if(t != null && parentId.equals(t.getpId())) {
							return true;
						} else {
							return false;
						}
					}).sorted((o1 , o2) -> {
						Integer w1 = o1.getWeight();
						Integer w2 = o2.getWeight();
						if(w1 != null && w2 != null) {
							return w1.compareTo(w2);
						} else if(w1 == null && w2 != null) {
							return -1;
						} else if(w2 == null && w1 != null) {
							return 1;
						} else {
							return 0;
						}
					}).forEachOrdered((t) -> {
						result.add(t);
					});
				}
			}
		}
		return result;
	}
}
